package com.example.onlinemonitoring.comCenter;

import com.example.onlinemonitoring.Util.CRC16;
import com.example.onlinemonitoring.Util.CommPortManager;
import com.example.onlinemonitoring.Util.HexUtil;
import com.example.onlinemonitoring.Util.IEEE754Utils;
import com.example.onlinemonitoring.model.Fdjpdsensor;
import com.example.onlinemonitoring.model.Fdjthsensor;
import com.example.onlinemonitoring.model.Gisblqsensor;
import com.example.onlinemonitoring.model.O2andsf6sensor;
import com.example.onlinemonitoring.model.common.MyResult;
import com.example.onlinemonitoring.model.common.pagebase;
import com.example.onlinemonitoring.model.Fdjpdhistory;
import com.example.onlinemonitoring.model.Appdevice;
import com.example.onlinemonitoring.model.Bxsusbpdsensor;
import com.example.onlinemonitoring.model.Byqpdsensor;
import com.example.onlinemonitoring.model.Dlhlsensor;
import com.example.onlinemonitoring.serviceImpl.FdjpdsensorServiceImpl;
import com.example.onlinemonitoring.serviceImpl.FdjthsensorServiceImpl;
import tk.mybatis.mapper.genid.GenId.NULL;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.context.annotation.Scope;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.TimerTask;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * FdjpdCom
 * 发电机局放
 * 用于接收和发送发电机局放设备数据消息
 * @author zzc
 * @date 2023-10-11
 */
@Service("fdjpdCom")
@Scope("prototype")
public class FdjpdCom extends CommPortManager {
        @Autowired
        private FdjpdsensorServiceImpl fdjpdsensorServiceImpl;//发电机局放服务器接口函数
        @Autowired
        private FdjthsensorServiceImpl fdjthsensorServiceImpl;//发电机局放温湿度传感器服务器接口函数
        Process pro=null;//定义一个指向Process的指针
         int timercount=0;//一个时间数的整型变量
         Boolean Sendfalg=true;//一个发送标记的布尔型变量
        // Lock lck = new ReentrantLock();
        private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();//定义一个读写锁
        private final Lock readLock = readWriteLock.readLock();//定义一个读锁
        private final Lock writeLock = readWriteLock.writeLock();//定义一个写锁
        float Ptphase = 0;//相位变量
        int addrserverindex=0;//服务器地址变量
/**
 * 接收发电机局放设备数据消息
 * 
 * @param str 数据消息
 * 
 */
        @Override
        public void receiveData(String str) {
            try {
               // writeLock.lock();
                receiveDatas(str);//接收数据函数
               // writeLock.unlock();
            } catch (Exception ex) {
                ex.printStackTrace();
                setText("从设备返回的数据有误！请检查串口！");
            }
        }
        public void receiveDatas(String str) {
            str = str.toUpperCase();//转大写字符
            setText(str);//显示打印数据
            //条件判断自己写
            String addrstr = str.substring(0, 2);//字符型地址
            Integer addrint = parseHex4(addrstr);//整型地址
    

            if (str.length()<12)//数据长度
            return;
            String cstr = String.format("%02x0502001C3F002104EC147B3F0000004228999A00000000C226C28F461A1e0003A6",addrint);
            String cmdstr = str.substring(2, 4);

            String currentPath = System.getProperty("user.dir");
            String str_path=currentPath + "\\usbpdman.exe";
            //String str_path="D:\\变电站在线监测\\usbpdman.exe";
            //int timersp = (int) Math.round(ad.getTimersp() * 1000);
            float delay = 2 / (ad.getBaudrate())*1000;
            int startindex=6;
            try {
                if(ad.getCommunicationmode()==2 &&cmdstr.equals("05"))
                {
                    reSend[addrint] = 0;
                    addrindex++;
                    setText("执行任务 "+ ad.getName());
                    if(pro==null)
                    {
                        Runtime rt = Runtime.getRuntime();
                        pro=rt.exec(str_path);
                        Thread.sleep(timersp/2+ 40 + (int)delay);
                    }
                    if(pro.isAlive())
                    {
                        setText("等待，任务 "+ ad.getName());
                        timercount++;
                        if(timercount>60)
                        {
                            pro.destroy();
                            timercount = 0;
                        }
                            
                        //Thread.sleep(1000);
                    }
                    else
                    {
                        pro.destroy();
                        Runtime rt = Runtime.getRuntime();
                        pro=rt.exec(str_path);
                        Thread.sleep(timersp/2+ 40 + (int)delay);
                    }


                    // Fdjpdsensor fdjpdsensor = new Fdjpdsensor();
                    // fdjpdsensor.setStationid(ad.getStationid());
                    // fdjpdsensor.setDeviceaddr(addrint);
                    // fdjpdsensor.setDevicegroup(ad.getDevicegroup());
                    // MyResult<Fdjpdsensor> res = fdjpdsensorServiceImpl.getList(fdjpdsensor);
                    // for (int i = 0; i < res.getCount(); i++) {
                        
                    //     //查询对象
                    //     Fdjpdsensor record = res.getData().get(i);
                    //     if (record == null) {
                    //         setText("当前数据库无监测点：设备地址" + 1 + "的监测点" + (i+1)+ " ！ 请先添加该监测点！");
                    //         return;
                    //     }
                    //     if(record.getInuse()==0)
                    //     return;
                    //     if(record.getPointaddr()==1&&record.getDeviceaddr()==1)
                    //     {
                    //        // Ptphase=record.getLastphase();
                    //     }
                    //     else
                    //     {
                    //         record.setLastphase(Ptphase);
                    //     }
                    //     fdjpdsensorServiceImpl.Update(record, false);
                    // }
                }
                if(ad.getCommunicationmode()==3)
                {
                    reSend[addrint] = 0;
                   // addrserverindex++;
                    if(cmdstr.equals("03"))
                    Send(cstr);

                    startindex=6;
                    float   temperaturevalue1 = (parseHex88(str.substring(startindex , startindex +=4))/10);  
                    float humidityvalue1 = (parseHex88(str.substring(startindex , startindex +=4))/10);
    
                    setText("温度：" + temperaturevalue1 + "℃ " + " 湿度: " + humidityvalue1 + "% "+"的监测点" +addrint  );
                    Fdjpdsensor fdjpdsensor = new Fdjpdsensor();
                    fdjpdsensor.setStationid(ad.getStationid());
                    fdjpdsensor.setDeviceaddr(addrint);
                    fdjpdsensor.setDevicegroup(ad.getDevicegroup());
                    MyResult<Fdjpdsensor> res = fdjpdsensorServiceImpl.getList(fdjpdsensor);
                    for (int i = 0; i < res.getCount(); i++) {
                        
                        //查询对象
                        Fdjpdsensor record = res.getData().get(i);
                        if (record == null) {
                            setText("当前数据库无监测点：设备地址" + 1 + "的监测点" + (i+1)+ " ！ 请先添加该监测点！");
                            return;
                        }
                        if(record.getInuse()==0)
                        continue;

                        record.setLasthumidityvalue(humidityvalue1);
                        record.setLasttemperaturevalue(temperaturevalue1);
                        AddAndUpdate(record);
                    }
                    //Thread.sleep(1000);
                }        
            } catch (Exception EX) {
                    setText(EX.toString());
            }
           


        }
        @Transactional
        private void AddAndUpdate(Fdjpdsensor record) {
            int alarmLevel = 0;// 报警等级
            String alarmMessage = "";// 报警消息
            //报警逻辑
            //这里写报警逻辑
            if (
                // record.getDischargecountalarmvalue() == null ||
                // record.getDischargecountalarmrelievevalue() == null ||
                // record.getDischargecountwarnvalue() == null ||
                // record.getDischargecountwarnrelievevalue() == null||
                record.getDischargeamountalarmvalue() == null ||
                record.getDischargeamountalarmrelievevalue() == null ||
                record.getDischargeamountwarnvalue() == null ||
                record.getDischargeamountwarnrelievevalue() == null 
        ) {
            setText("设备地址" + record.getDeviceaddr() + " 未设置报警值！");
            return;
        } 
        List<Integer> array = new ArrayList<>();
        float chargeamountmax=isnull(record.getLastdischargeamount());
        record.setLastchargemountalarmstatus(
            GetAlarmStatus(isnull(chargeamountmax), isnull(record.getDischargeamountalarmvalue()),
                    isnull(record.getDischargeamountalarmrelievevalue()), isnull(record.getDischargeamountwarnvalue()),
                    isnull(record.getDischargeamountwarnrelievevalue()),
                    isnull(record.getLastchargemountalarmstatus()), true, "放电量", record.getDevicegroup(), record.getDeviceaddr(),
                    record.getPointname(),record.getPointaddr()));
        alarmMessage += GetAlarmMessage(record.getLastchargemountalarmstatus(), "放电量");
        array.add(record.getLastchargemountalarmstatus());
        record.setLasttemperaturealarm(
            GetAlarmStatus(isnull(record.getLasttemperaturevalue()), isnull(record.getTemperaturealarmvalue()),
                    isnull(record.getTemperaturealarmrelievevalue()), isnull(record.getTemperaturewarnvalue()),
                    isnull(record.getTemperaturewarnrelievevalue()),
                    isnull(record.getLasttemperaturealarm()), true, record.getPointname() + "温度",
                    record.getDevicegroup(), record.getDeviceaddr(),
                    record.getPointname(), record.getPointaddr()));
    alarmMessage += GetAlarmMessage(record.getLasttemperaturealarm(), "温度");
    array.add(record.getLasttemperaturealarm());
    record.setLasthumidityalarm(
            GetAlarmStatus(isnull(record.getLasthumidityvalue()), isnull(record.getHumidityalarmvalue()),
                    isnull(record.getHumidityalarmrelievevalue()), isnull(record.getHumiditywarnvalue()),
                    isnull(record.getHumiditywarnrelievevalue()),
                    isnull(record.getLasthumidityalarm()), true, record.getPointname() + "湿度",
                    record.getDevicegroup(), record.getDeviceaddr(),
                    record.getPointname(), record.getPointaddr()));
    alarmMessage += GetAlarmMessage(record.getLasthumidityalarm(), "湿度");
    array.add(record.getLasthumidityalarm());
        int usbstatus = isnull(record.getLastusbstatus());
        array.add(usbstatus);
        if(usbstatus==1)
            alarmMessage +="USB连接异常";
        if(usbstatus==2)
            alarmMessage +="USB连接失败";
            //setText("温度：" + alarmLevel + "℃ " + " 湿度: " + alarmMessage + "% " );
        alarmLevel = HexUtil.MAX(array);
            record.setLastalarmlevel(alarmLevel);
            record.setLastalarmmessage(alarmMessage);
            record.setLastcommunicationstatus(0);
            //record.setLastdatatime(new Date());
           // record.setLasthisdatatime(addHistory(record));
          
            if ( fdjpdsensorServiceImpl.Update(record, false) == 0) {
                setText("更新实时数据失败，请检查数据库连接");
            }
        }
        private Date addHistory(Fdjpdsensor sensor) {
            if (sensor != null) {
                if (sensor.getLasthisdatatime() == null) {
                    //add(sensor);
                    return new Date();
                } else {
                    long lasttime = 0;
                    long nowtime = 0;
                    try {
                        lasttime = HexUtil.todate(sensor.getLasthisdatatime()).getTime();
                        nowtime = HexUtil.todate(new Date()).getTime();
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                    int timersp = 60000;
                    if (sensor.getLastalarmlevel() != 0) {
                        timersp = ad.getHisalarmtimersp()*1000;
                    } else {
                        timersp = ad.getHistimersp()*1000;
                    }
                    if (lasttime + timersp < nowtime) {
                        //add(sensor);
                        return new Date();
                    }
                }
            }
            return null;
        }

        private void add(Fdjpdsensor sensor) {
            Fdjpdhistory his = new Fdjpdhistory();
            his.setDeviceaddr(sensor.getDeviceaddr());
            his.setDevicegroup(sensor.getDevicegroup());
            his.setAlarmlevel(sensor.getLastalarmlevel());
            his.setAlarmmessage(sensor.getLastalarmmessage());
            his.setDatatime(sensor.getLastdatatime());
            his.setPointname(sensor.getPointname());
            his.setStationid(sensor.getStationid());
            //需要添加自己定义的属性
            //  todo
            fdjpdsensorServiceImpl.Add(his);
        }

    public static float parseHex88(String num) {
        int ret = Integer.parseInt(num, 16);
        if (num.length() == 2) {
            return ret;
        } else if (num.length() == 4) {
            ret = ((ret & 0x8000) > 0) ? (ret - 0x10000) : (ret);
            return ret;
        } else {
            throw new NumberFormatException("Wrong length: " + num.length() + ", must be 4.");
        }
    }

        @Async("threadPool")
        public void startSendThread(Appdevice Appdevice) throws Exception {
            checkType = "crc16";

            issend.put(Thread.currentThread().getId(), true);
           
            String cstr = "";
            String cmdtype = "";
            String nametype = "";
             String currentPath = System.getProperty("user.dir");
             String str_path=currentPath + "\\usbpdman.exe";
                //String str_path="D:\\变电站在线监测\\usbpdman.exe";
             int timersp = (int) Math.round(Appdevice.getTimersp() * 1000);
             float delay = 2 / (Appdevice.getBaudrate())*1000;
            // if(pro==null)
            // {
            //     Runtime rt = Runtime.getRuntime();
            //     pro=rt.exec(str_path);
            // }
            // timerPd.schedule(new TimerTask() {
            //      @Override
            //      public void run() {
            //         if(Appdevice.getCommunicationmode()==2)
            //         {
            //             System.out.println("时间到，执行任务 "+ Appdevice.getName());

            //             Process pro=null;
            //             try {
            //             Runtime rt = Runtime.getRuntime();
            //             pro=rt.exec(str_path);
            //             Thread.sleep(40 + (int)delay);
            //             if(pro.isAlive())
            //             {
            //                 Thread.sleep(1000);
            //             }

            //     } catch (Exception EX) {
            //          setText(EX.toString());
            //     }
            // }
            //String cstr = "";
            while (issend.get(Thread.currentThread().getId()) != null) {
                if (addrindex > Appdevice.getAddrmax() || addrindex < Appdevice.getAddrmin())
                    addrindex = Appdevice.getAddrmin();


                try {

                    if(Appdevice.getCommunicationmode()==1)
                     {
                        setText("执行任务 "+ ad.getName());
                        if(pro==null)
                        {
                            Runtime rt = Runtime.getRuntime();
                            pro=rt.exec(str_path);
                            Thread.sleep(timersp/2+ 40 + (int)delay);
                        }
                        if(pro.isAlive())
                        {
                           setText("等待，任务 "+ ad.getName());
                           timercount++;
                           if(timercount>60)
                            {
                              pro.destroy();
                                timercount = 0;
                            }
                                
                            //Thread.sleep(1000);
                        }
                        else
                        {
                            pro.destroy();
                            Runtime rt = Runtime.getRuntime();
                            pro=rt.exec(str_path);
                            Thread.sleep(timersp/2+ 40 + (int)delay);
                        }
                        Fdjthsensor fdjthsensor =  new Fdjthsensor();
                        fdjthsensor.setStationid(ad.getStationid());
                        fdjthsensor.setDevicegroup(ad.getDevicegroup());
                        fdjthsensor.setDeviceaddr(1);
                        fdjthsensor = fdjthsensorServiceImpl.getModel(fdjthsensor);
                        if (fdjthsensor == null) {
                            setText("当前数据库无监测点：设备地址" + 1 + "的监测点" +1 + " ！ 请先添加该监测点！");
                            return;
                        }


                        if(fdjthsensor.getInuse()==0)
                            return;
                        cstr = String.format(String.format("%02X0304%04X%04X", addrindex, (short)Math.round(isnull(fdjthsensor.getLasttemperaturevalue1()*10)),(short)Math.round(isnull(fdjthsensor.getLasthumidityvalue1()*10))));
                        cstr = cstr + CRC16.calcCrc16(cstr);

                        Send(cstr);     
                        //Sendfalg=false;                
                        
                     }
                     if(Appdevice.getCommunicationmode()==2)
                     {
                        Fdjthsensor fdjthsensor =  new Fdjthsensor();
                        fdjthsensor.setStationid(ad.getStationid());
                        fdjthsensor.setDevicegroup(ad.getDevicegroup());
                        fdjthsensor.setDeviceaddr(1);
                        fdjthsensor = fdjthsensorServiceImpl.getModel(fdjthsensor);
                        if (fdjthsensor == null) {
                            setText("当前数据库无监测点：设备地址" + 1 + "的监测点" +1 + " ！ 请先添加该监测点！");
                            return;
                        }


                        if(fdjthsensor.getInuse()==0)
                            return;
                        cstr = String.format(String.format("%02X0304%04X%04X", addrindex, (short)Math.round(isnull(fdjthsensor.getLasttemperaturevalue1()*10)),(short)Math.round(isnull(fdjthsensor.getLasthumidityvalue1()*10))));
                        cstr = cstr + CRC16.calcCrc16(cstr);
                        Send(cstr);     
                        //Sendfalg=false;                
                        
                     }

                    // Fdjpdsensor fdj = new Fdjpdsensor();
                    // fdj.setStationid(ad.getStationid());
                    // fdj.setDevicegroup(ad.getDevicegroup());
                    // MyResult<Fdjpdsensor> res = fdjpdsensorServiceImpl.getList(fdj);
                    // int index = 0;
                    // for (int i = 0; i < res.getCount(); i++) {
                    //      Fdjpdsensor record = res.getData().get(i);
                    //  if (record == null) {
                    //      setText("当前数据库无监测点：设备地址" + addrindex + "的监测点" + i+1 + " ！ 请先添加该监测点！");
                    //      return;
                    //  }

                    // if(record.getInuse()==0)
                    //     continue;
                    // cstr += "7F"+ ",";
                    // cstr += String.format("%02X", record.getDeviceaddr())+ ",";
                    // cstr += "A6"+ ",";// 功能码
                    //  cstr += String.format("%02X", record.getPointaddr())+ ",";
                    // cstr += record.getLastdischargetype()+ ",";
                    // cstr += record.getLastchargecount()+ ",";
                    // cstr += record.getLastdischargeamount()+ ",";
                    // cstr += record.getLastphase()+ ",";
                    // cstr += "7F";
                    // //cstr = cstr + CRC16.calcCrc16(cstr);
                    // Send(cstr);
                    // }


                    // Fdjpdhistory fdjhis = new Fdjpdhistory();
                    // fdjhis.setStationid(ad.getStationid());
                    // fdjhis.setDeviceaddr(null);
                    // fdjhis.setDevicegroup(ad.getDevicegroup());
                    // pagebase pagebase = new pagebase();
                    // pagebase.setBegintime(null);
                    // pagebase.setEndtime(null);
                    // pagebase.setPage(1);
                    // pagebase.setLimit(40);
                    // pagebase.setPagecount(40);
                    // fdjhis.setPointaddr(null);

                    // MyResult<Fdjpdhistory> reshis = fdjpdsensorServiceImpl.getHisList(fdjhis,pagebase);
                    // for (int i = 0; i < reshis.getCount(); i++) {
                    //      Fdjpdhistory recordhis = reshis.getData().get(i);
                    //  if (recordhis == null) {
                    //      setText("当前数据库无监测点：设备地址" + addrindex + "的监测点" + i+1 + " ！ 请先添加该监测点！");
                    //      return;
                    //  }

                    // if(recordhis.getInuse()==0)
                    //     continue;
                    // cstr += "7F"+ ",";
                    // cstr += String.format("%02X", recordhis.getDeviceaddr())+ ",";
                    // cstr += "A7"+ ",";// 功能码
                    // cstr += String.format("%02X", recordhis.getPointaddr())+ ",";
                    // cstr += recordhis.getDischargetype()+ ",";
                    // cstr += recordhis.getChargecount()+ ",";
                    // cstr += recordhis.getDischargeamount()+ ",";
                    // cstr += recordhis.getPhase()+ ",";
                    // cstr += "7F";
                    // //cstr = cstr + CRC16.calcCrc16(cstr);
                    // Send(cstr);
                    // }

                } catch (Exception EX) {
                     setText(EX.toString());
                }
                 if(Appdevice.getCommunicationmode()==3)
                 {
                    if (addrserverindex > Appdevice.getAddrmax() || addrserverindex < Appdevice.getAddrmin())
                    addrserverindex = Appdevice.getAddrmin();

                    reSend[addrserverindex]++;
                    if (reSend[addrserverindex] > 3) {
                    fdjpdsensorServiceImpl.UpdateStatus(ad, addrserverindex,1);
                    reSend[addrserverindex] = 0;
                    //addrserverindex++;
                    //setText("UpdateStatus: "+ 1);
                    } 
                    addrserverindex++;
                    //setText("addrserverindex: "+addrserverindex+"reSend: "+  reSend[addrserverindex]);
                 }
                 else
                 {
                    reSend[addrindex]++;
                    if (reSend[addrindex] > 3) {
                    fdjpdsensorServiceImpl.UpdateStatus(ad, addrindex,1);
                    reSend[addrindex] = 0;
                    addrindex++;
                 }

                }
                Thread.sleep(timersp);
            }
           // pro.destroy();
            //if (timerFlag ==false)
           // timerPd.cancel(); //定时器终止
        //     }
        // },1000,timersp);
    }


        // @Async("threadPool")
        // public void startReceiveThread(){
        //     isrecv.put(Thread.currentThread().getId(), true);
        //     while (isrecv.get(Thread.currentThread().getId()) != null) {
        //         //这里根据实际协议替换,解析方法recvCrc16;recvSum();
        //         recv();
        //         try {
        //             Thread.sleep(interval);
        //         } catch (InterruptedException e) {
        //             e.printStackTrace();
        //         }
        //     }
        // }
}
